﻿//++
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
// Module Name:
//
//  Task.cs
//    
// Abstract:
//
//  This module implements the Task class. This is the base class for all tasks.
//
//--

using System;
using System.Diagnostics;

using Microsoft.OfficeCommunicationsServer.Applications.Common;

namespace Microsoft.EnhancedReminders.Scheduler
{
    /// <summary>
    /// The base class for all tasks.
    /// </summary>
    internal abstract class Task
    {
        // Context associated with this task
        protected readonly TaskContext _taskContext;

        // Indicates if the task has completed
        private bool _completed;

        /// <summary>
        /// ctor.
        /// </summary>
        /// <param name="taskContext">Task context</param>
        protected Task(TaskContext taskContext)
        {
            Debug.Assert(taskContext != null, "taskContext != null");
            Debug.Assert(taskContext.Context != null, "taskContext.Context != null");

            _taskContext = taskContext;
        }

        /// <summary>
        /// Starts execution of this task.
        /// </summary>
        internal abstract void Begin();

        /// <summary>
        /// Returns the logging context associated with this task.
        /// </summary>
        internal Context Context
        {
            get
            {
                return _taskContext.Context;
            }
        }

        /// <summary>
        /// Raised when this task comepletes.
        /// </summary>
        internal event EventHandler<TaskCompletedEventArgs> Completed;

        /// <summary>
        /// Raises the Completed event.
        /// </summary>
        /// <param name="args">Task event args</param>
        protected void RaiseCompleted(TaskCompletedEventArgs args)
        {
            Debug.Assert(args != null, "args != null");
            Debug.Assert(!_completed, "!_completed");

            // This is used for debugging and ensures the above assert will be raised if the completed event is raised more than once
            _completed = true;

            EventHandler<TaskCompletedEventArgs> completed = Completed;

            if (completed != null)
            {
                completed(this, args);
            }
        }
    }
}
